package cn.whdream.datastructure.sort;

import java.util.Arrays;
/**
 * 
 * @author blackjuly
 * 快速排序 TODO 之后需要进行整理复盘
 */
public class QuickSort {
	public static void main(String[] args) {
		int[] arr = {-9,78,0,23,-567,70};
		quickSort(arr,0,arr.length-1);
		print(arr);
	}

	private static void print(int[] arr) {
		System.out.println(Arrays.toString(arr));
	}

	private static void quickSort(int[] arr, int left, int right) {
		int l = left;//左下标
		int r = right;//右下标
		int temp;
		//中轴值,无论是什么数字，就取中间下标的数字 value
		int pivot = arr[(left +right)/2];
		//指针保证 l在左边的时候，r在右边的时候
		while (l < r) {
			//左边的值，小于中间值则；指到下一个
			while (arr[l] < pivot) {
				l++;
			}
			//右边的值，大于中间值；则指到下一个
			while (arr[r] > pivot) {
				r--;
			}
			//如果已经不符合条件直接关闭，
			if(l >= r) {
				break;
			}
			//同时符合了 左边值大于 pivot和右边值小于 pivot，两边的值进行交换
			temp = arr[l];
			arr[l] = arr[r];
			arr[r] =temp;
			//左边的时候， r 光标走到了边界值，尤其到了只剩下两个数字的时候，需要通过
			if(arr[l] == pivot) {
				System.out.println("左光标和中间值相等");
				System.out.println("r:"+r+" arr[r]"+arr[r]);
				System.out.println("l:"+l+" arr[l]"+arr[l]);
				r--;
			}
			//右边的时候， l 光标走到了边界值，尤其到两个数字的的时候，需要通过一下 ？？？不太确定这部分的思路
			if(arr[r] == pivot) {
				System.out.println("右光标和中间值相等");
				System.out.println("r:"+r+" arr[r]"+arr[r]);
				System.out.println("l:"+l+" arr[l]"+arr[l]);
				l++;
			}
		}
		//相等的时候，递归会跳过循环；则
		if(l == r) {
			l++;
			r--;
		}
		//右边边的光标已经走到了和left相等or小于left的位置，则不再递归
		if (left < r) {
			quickSort(arr, left, r);
		}
		//左边的光标已经走到了和right相等或者 小于right的位置，则不递归
		if (right > l) {
			quickSort(arr, l, right);
		}
	}
	
	public static void quickSort2(int[] arr,int left, int right) {
		int l = left; //左下标
		int r = right; //右下标
		//pivot 中轴值
		int pivot = arr[(left + right) / 2];
		int temp = 0; //临时变量，作为交换时使用
		//while循环的目的是让比pivot 值小放到左边
		//比pivot 值大放到右边
		while( l < r) { 
			//在pivot的左边一直找,找到大于等于pivot值,才退出
			while( arr[l] < pivot) {
				l ++;
			}
			//在pivot的右边一直找,找到小于等于pivot值,才退出
			while(arr[r] > pivot) {
				r --;
			}
			//如果l >= r说明pivot 的左右两的值，已经按照左边全部是
			//小于等于pivot值，右边全部是大于等于pivot值
			if( l >= r) {
				break;
			}
			
			//交换
			temp = arr[l];
			arr[l] = arr[r];
			arr[r] = temp;
			
			//如果交换完后，发现这个arr[l] == pivot值 相等 r--， 前移
			if(arr[l] == pivot) {
				r --;
			}
			//如果交换完后，发现这个arr[r] == pivot值 相等 l++， 后移
			if(arr[r] == pivot) {
				l ++;
			}
		}
		
		// 如果 l == r, 必须l++, r--, 否则为出现栈溢出
		if (l == r) {
			l += 1;
			r -= 1;
		}
		//向左递归
		if(left < r) {
			quickSort2(arr, left, r);
		}
		//向右递归
		if(right > l) {
			quickSort2(arr, l, right);
		}
		
		
	}
}
